/*****************************
 *@file: GameScene
 *@author: 陈吕唐
 *@desc: 游戏战斗场景
 *@date: 2024-03-06	14:30
 *****************************/
import { _decorator, Button, Component, EditBox, EPhysics2DDrawFlags, Label, Node, PhysicsSystem2D, Prefab } from 'cc';
import { DEBUG } from 'cc/env';
import { BuildBaseFightComp } from '../game/BuildBaseFightComp';
import { BaseFightLogic } from '../game/core/BaseFightLogic';
import IBaseFightAttribute from '../game/core/data/IBaseFightAttribute';
import { MGameEvent } from '../game/core/MGameEvent';
import { GameStatueEnum } from '../game/enum/GameStatueEnum';
import GameSingle from '../game/GameSingle';
import { HeroBaseFightComp } from '../game/HeroBaseFightComp';
import IGameScene from '../game/IGameScene';
import { MonsterBaseFightComp } from '../game/MonsterBaseFightComp';
const { ccclass, property } = _decorator;

@ccclass('GameScene')
export class GameScene extends Component implements IGameScene {
    /****************************************************************************************************************
     *Readonly 常量
     ****************************************************************************************************************/
    /****************************************************************************************************************
     *Property 定义变量
     ****************************************************************************************************************/
    /**
     * 怪物预制体
     */
    private monsterPrefabMap: Map<number, Prefab> = new Map();

    /**
     * 游戏状态
     */
    private gameStatue: GameStatueEnum = GameStatueEnum.INIT;
    /***************************************************************
     *PropertyUI 引用的控件
     ***************************************************************/
    @property({ group: { name: 'Game', id: '1' }, type: BuildBaseFightComp, tooltip: `城墙组件` })
    private wallFight: BuildBaseFightComp = undefined!;

    @property({ group: { name: 'Game', id: '1' }, type: HeroBaseFightComp, tooltip: `测试用英雄组件` })
    private heroFight: HeroBaseFightComp = undefined!;

    @property({ group: { name: 'Game', id: '1' }, type: Node, tooltip: `怪物容器组件` })
    private monsterLayout: Node = undefined!;

    @property({ group: { name: 'Game', id: '1' }, type: Node, tooltip: `英雄容器组件` })
    private heroLayout: Node = undefined!;

    @property({ group: { name: 'DEBUG', id: '2' }, type: Button, tooltip: `按钮组件` })
    private testButton: Button = undefined!;

    @property({ group: { name: 'DEBUG', id: '2' }, type: Button, tooltip: `测试添加怪物按钮按钮组件` })
    private testAddButton: Button = undefined!;

    @property({ group: { name: 'DEBUG', id: '2' }, type: Label, tooltip: `测试文本文本组件` })
    private testLabel: Label = undefined!;

    @property({ group: { name: 'DEBUG', id: '2' }, type: EditBox, tooltip: `测试输入框组件` })
    private testIdEditBox: EditBox = undefined!;
    /****************************************************************************************************************
     * Lifecycle 生命周期相关方法
     ****************************************************************************************************************/
    protected onLoad(): void {
        if (DEBUG) {
            this.openPhysicsDebug();
        }

        this.testButton.node.active = false;
        this.testButton.node.on(Button.EventType.CLICK, this.onClickTest, this);
        this.testAddButton.node.on(Button.EventType.CLICK, this.addMonster, this);
        this.wallFight.node.on(MGameEvent.FightEvent.DEAD_STATE, this.gameLose);
        // this.loadMonster();
        let promise = GameSingle.single.loadAssets();
        promise.then(() => {
            this.testButton.node.active = true;
        });
    }

    protected onEnable(): void {

    }
    /****************************************************************************************************************
     * Public 公有方法
     ****************************************************************************************************************/
    /****************************************************************************************************************
     * private 私有方法
     ****************************************************************************************************************/

    private onClickTest() {
        // this.initLevelData();
        this.gameStart();
    }


    /******************************
     * 英雄相关
     ******************************/

    /******************************
     * 怪物相关
     ******************************/
    /**
     * 添加一只怪物到场景中
     */
    private addMonster() {
        let monsterData = this.createTestMonster();
        let node = GameSingle.single.createMonsterNode(monsterData);
        let y = Math.random() * 2340 - 1170;
        y = 0;
        node.setPosition(0, y);
        this.monsterLayout.addChild(node);
    }
    /*********************************************************
     * 调试相关
     ********************************************************/
    /**
     * 开启物理调试
     */
    private openPhysicsDebug() {
        PhysicsSystem2D.instance.debugDrawFlags = EPhysics2DDrawFlags.Aabb |
            EPhysics2DDrawFlags.Pair |
            EPhysics2DDrawFlags.CenterOfMass |
            EPhysics2DDrawFlags.Joint |
            EPhysics2DDrawFlags.Shape;
    }
    private createTestWall(): IBaseFightAttribute {
        let value: IBaseFightAttribute = {
            hp: 100,
            spd: 100,
            atk: 100,
            def: 50,
        }
        return value;
    }

    /**
     * 
     */
    private createTestHero(): IBaseFightAttribute {
        let value: IBaseFightAttribute = {
            hp: 100,
            spd: 100,
            atk: 100,
            def: 50,
        }
        return value;
    }

    /**
     * 创建测试
     * @returns 
     */
    private createTestMonster(): IBaseFightAttribute {
        let value: IBaseFightAttribute = {
            hp: 100,
            spd: 100,
            atk: 100,
            def: 50,
        }
        return value;
    }
    /*********************************************************
     * 
     ********************************************************/
    /**
     * 战斗开始,要先初始化关卡数据
     */
    private gameStart() {


        if (DEBUG) {
            let id = parseInt(this.testIdEditBox.string);
            GameSingle.single.testBulletId = id;
        }


        GameSingle.single.scene = this;

        if (!this.monsterLayout.hasEventListener(Node.EventType.CHILD_REMOVED, this.gameJudge, this)) {
            this.monsterLayout.on(Node.EventType.CHILD_REMOVED, this.gameJudge, this);
        }

        /**
         * 怪物开始行动
         */
        let monsters: MonsterBaseFightComp[] = this.monsterLayout.getComponentsInChildren(MonsterBaseFightComp);
        for (let i = 0; i < monsters.length; i++) {
            const element = monsters[i];
            element.fightStart();
        }

        /**
         * 英雄开始行动
         */
        let heros: HeroBaseFightComp[] = this.heroLayout.getComponentsInChildren(HeroBaseFightComp);
        for (let i = 0; i < heros.length; i++) {
            const element = heros[i];
            element.init(this.createTestHero())
            element.fightStart();
        }

        /**
         * 城墙
         */
        let wallData = this.createTestWall();
        this.wallFight.init(wallData);
        this.wallFight.fightStart();

        /**
         * 
         */
        this.gameStatue = GameStatueEnum.GAME_ING;
    }

    private gameEnd() {
        this.monsterLayout.off(Node.EventType.CHILD_REMOVED, this.gameJudge, this);
        this.heroLayout.removeAllChildren();
    }

    /**
     * 游戏胜利判断
     */
    private gameJudge() {
        if (this.monsterLayout.children.length <= 0) {
            this.gameWin();
            return;
        }
    }


    private gameLose() {
        console.log("游戏结束");
        this.testLabel.string = `战斗失败`;
        this.gameEnd();
    }

    private gameWin() {
        console.log("游戏胜利");
        this.testLabel.string = `战斗胜利`;
        this.gameEnd();
    }
    /****************************************************************************************************************
     * Property Get && Set 属性的 get && set 函数
     ****************************************************************************************************************/
    public get monsters(): BaseFightLogic[] {
        let monster = this.monsterLayout.getComponentsInChildren(BaseFightLogic);
        return monster;
    }
}


